from random import randint

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.verifications import constants
from apps.verifications.serializers import RegisterSMSCodeSerializer
from libs.captcha.captcha import captcha
from django_redis import get_redis_connection
from rest_framework.generics import GenericAPIView
from libs.yuntongxun.sms import CCP
from rest_framework import status

class RegisterImageCodeView(APIView):
    """
    生成验证码的接口
     GET      /verifications/imagecodes/(?P<image_code_id>.+)/
    1. 要不要进行参数的传递.  需要传递参数, 因为我们获取了验证码图片之后,肯定是需要进行校验
        所以我们需要传递一个 能够确保校验的时候能够找到对应的比对对象
    2. 验证码生成图片的同时需要 把生成的校验码 保存起来 -->redis
    """
    def get(self, request, image_code_id):
        # 生成图片和验证码
        text, image = captcha.generate_captcha()

        # 把验证码保存到redis中
        # 连接redis,参数的setting中的redis中的code
        redis_conn = get_redis_connection('code')

        # 把验证码保存起来
        redis_conn.setex('img_%s' % image_code_id, constants.IMAGE_CODE_EXPIRE_TIME, text)

        # 返回图片
        # content_type = mime
        # text/javascript  image/jpeg
        return HttpResponse(image, content_type='image/jpeg')


class RegisterSMSCodeView(GenericAPIView):
    """
       根据用户提交的验证码,发送短信验证码 xxxx指的是4位数
       GET    /verifications/smscodes/(?P<mobile>1[345789]\d{9})/?text=xxxx & image_code_id=xxxx
       1. 当我们点击按钮的时候 ,首先应该把验证码的内容发送给我，我进行校验
       2. 校验成功了,我们需要给手机发送短信验证码
       3. 把短信存起来,设置有效期
       4. 我们需要设置发送的标记,放置用户频繁操作
    """
    serializer_class = RegisterSMSCodeSerializer
    def get(self, request, mobile):
        # 验证码内容的校验(序列化器)
        # 数据校验，反序列化
        serializer = self.get_serializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        # 判断用户是否已经有发送记录，防止用户频繁操作
        # 记录发送状态
        redis_conn = get_redis_connection('code')
        flag = redis_conn.get('sms_flag_%s' % mobile)
        if flag:
            return Response(status=status.HTTP_429_TOO_MANY_REQUESTS)

        # 生成短信验证码
        sms_code = '%06d' % randint(0, 999999)
        print(sms_code)

        # # 记录短信验证码
        # redis_conn.setex("sms_%s" % mobile, constants.SMS_CODE_EXPIRE_TIME, sms_code)
        #
        # # 记录发送状态(点击发送之后，60秒之内不能点击，1代表已经点击发送)
        # redis_conn.setex('sms_flag_%s' % mobile, 60, 1)

        # 创建管道
        pl = redis_conn.pipeline()
        # 将以上两步合并为一步
        pl.setex("sms_%s" % mobile, constants.SMS_CODE_EXPIRE_TIME, sms_code)
        pl.setex('sms_flag_%s' % mobile, 60, 1)
        # 执行管道
        pl.execute()

        # 发送
        # ccp = CCP()
        # ccp.send_template_sms(mobile, [sms_code, 5], 1)
        from celery_tasks.sms.tasks import send_sms_code
        send_sms_code.delay(mobile, sms_code)

        # 由于短信的下发跟返回响应是同步的操作，为了防止出现等待的情况
        # 我们采用Celery异步的方式来实现短信下发

        return Response({'message': 'ok'})
